"""
2.	给定的五个VOC“锚框”Anchors的宽高数据，和目标真实框GT数据。（24分）
Anchors: (1.3221, 1.73145), (3.19275, 4.00944), (5.05587, 8.09892), (9.47112, 4.84053), (11.2364, 10.0071)
GT：中心点(7, 7)，边框宽高(10, 5)
"""
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

anchors_pairs = np.array([
    (1.3221, 1.73145), (3.19275, 4.00944), (5.05587, 8.09892), (9.47112, 4.84053), (11.2364, 10.0071)
])
gt_pair = np.array([10, 5])


def length2xyxy(length_pair):
    return (
        13 / 2 - length_pair[0] / 2,
        13 / 2 - length_pair[1] / 2,
        13 / 2 + length_pair[0] / 2,
        13 / 2 + length_pair[1] / 2,
    )


anchors = np.array([length2xyxy(pair) for pair in anchors_pairs])
gt = np.array(length2xyxy(gt_pair))
print('Anchors:')
print(anchors)
print('Gt:')
print(gt)

# ①	分别计算GT与五个Anchors的交并比IOU，并输出他们的值
max_x1 = np.maximum(gt[0], anchors[:, 0])
min_x2 = np.minimum(gt[2], anchors[:, 2])
max_y1 = np.maximum(gt[1], anchors[:, 1])
min_y2 = np.minimum(gt[3], anchors[:, 3])
xx = np.maximum(0., min_x2 - max_x1 + 1)
yy = np.maximum(0., min_y2 - max_y1 + 1)
I = xx * yy
U = (gt[2] - gt[0] + 1) * (gt[3] - gt[1] + 1) \
    + (anchors[:, 2] - anchors[:, 0] + 1) * (anchors[:, 3] - anchors[:, 1] + 1)\
    - I
iou = I / (U + 1e-20)
print('IOU: ', iou)

# ②	交并比IOU按降序排序，并打印输出
orders = iou.argsort()[::-1]
print('交并比IOU按降序排序，并打印输出')
print(orders)

# ③	选择与真实框GT最大交并比的“锚框”Anchor，图像显示该“锚框”和真实框GT
plt.figure(figsize=[6, 6])
plt.xlim((0, 13))
plt.ylim((0, 13))
max_idx = orders[0]
anchors = anchors - 13 / 2 + 7
anchor = anchors[max_idx]
gt = gt - 13 / 2 + 7


def draw_rect(x1, y1, x2, y2, color, label):
    plt.plot((x1, x2), (y1, y1), color=color)
    plt.plot((x1, x2), (y2, y2), color=color)
    plt.plot((x1, x1), (y1, y2), color=color)
    plt.plot((x2, x2), (y1, y2), color=color)
    plt.annotate(f'{label}', xy=(x1, y1))


def draw_rect_vec(orders, color):
    boxes = anchors[orders]
    x1 = boxes[:, 0]
    y1 = boxes[:, 1]
    x2 = boxes[:, 2]
    y2 = boxes[:, 3]
    plt.plot((x1, x2), (y1, y1), color=color)
    plt.plot((x1, x2), (y2, y2), color=color)
    plt.plot((x1, x1), (y1, y2), color=color)
    plt.plot((x2, x2), (y1, y2), color=color)
    for order in orders:
        plt.annotate(f'{order}', xy=(anchors[order, 0], anchors[order, 1]))


draw_rect(*anchor, 'blue', 'anchor')
draw_rect(*gt, 'red', 'gt')
draw_rect_vec(orders[1:], 'black')

plt.ylim(plt.ylim()[::-1])

plt.show()
